/**
 * 发布订阅则-全局状态管理
 * 优点：我们可以看到我们可以不适用任何的 eventName 就可以做到我们的事件监听，而且呢我们同一个事件可以加非常非常多的 observers 也就是说添加非常非常多的订阅者，
 * 之后呢我们通过 订阅者 来遍历去修改我们所有的订阅者的依赖
 * 当前呢也没有了我们之前使用 customeventname 命名会重复的问题，
 * 但是呢这里我们依然要注意一个问题就是我们当前添加 订阅者 和我们做 update 的操作也有一个严格的先后顺序，
 * 只有你先添加了 订阅者 之后你在做操作的时候才可以通知到你的订阅者，那么如果说你连订阅者都没有添加那我们直接执行 update 的
 * 操作它是可以通知到其它的订阅者，但是你当前需要的这个数据是没有的。
 */

// 在当前的 createStore 里面首先我们要接入一个 initData 的参数，那么这个呢就是我们默认的一些store的数据，
// 我们需要通过我们的方法去保存我们这个数据，这个时候呢大家一定会自然而然的想到闭包这样一个情况
export const createStore = (initData = {}) => (()=>{
  // 创建一个闭包，用于保存 initData 的数据
  let store = initData;
  const observers = []; // 管理所有的订阅者，依赖
  // 获取store
  const getStore = () => store;
  // 更新store
  const update = (value) => {
    // 如果传入的value不等于store
    if(value !== store){
      // 执行store的操作
      const oldValue = store;
      // 将 store 更新
      store = value;
      // 通知所有的订阅者，监听 store 的变化
      // observers 里面可能有一些异步的操作
      observers.forEach(async item => await item(store, oldValue));
    }
  }
  // 添加订阅者，它呢主要是为了添加一些我们需要对当前这个store对象改变做出相应变化的一些方法，也就是我们俗称的`订阅者`
  const subscribe = (fn) => {
    observers.push(fn);
  }
  return {
    getStore,
    update,
    subscribe
  };
})();
